package com.ymatou.iapi.productquery.compare;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.ymttest.utils.JsonBeanHelper;

public class AssertServiceHelper {
	//默认10秒
	public static boolean  assertTime(Date expectedDate, Date actualDate, String desc,boolean isWriteRet) {
		 return assertTime(expectedDate,actualDate,120,desc,isWriteRet);
	}
	
	
	public static boolean assertTime(Date expectedDate, Date actualDate, int timeDiffSecond,String desc,boolean isWriteRet) {
		
		LoggerHelper.verifyNotNull(expectedDate, desc + ",期待时间不该为空",isWriteRet);
		LoggerHelper.verifyNotNull(actualDate, desc + ",实际时间不该为空",isWriteRet);

		long time1 = expectedDate.getTime();
		long time2 = actualDate.getTime();
		return LoggerHelper.verifyEquals(true, Math.abs(time1 - time2) <= timeDiffSecond * 1000,
				desc+", 时间比较,期望时间[" + expectedDate + "],实际时间[" + actualDate + "] 误差应不超过 " + timeDiffSecond + "秒",isWriteRet);

	}
	
	


	public static boolean assertResultEqual(Map<String, Object> tgtRetMap, Map<String, Object> actRetMap, String desc,boolean isWriteRet) {
		LoggerHelper.verifyNotNull( tgtRetMap, desc +",tgtRetMap should not be null",isWriteRet);
		LoggerHelper.verifyNotNull( actRetMap, desc +",actRetMap should not be null",isWriteRet);
		
		boolean isRight = true;
		
		for (String actKey : tgtRetMap.keySet()) {
			if (actRetMap.containsKey(actKey)) {
				Object tgtNodeObj = tgtRetMap.get(actKey);
				Object actNodeObj = actRetMap.get(actKey);
				try {
					Object[] ret = checkWorkAround(tgtNodeObj, actNodeObj);
					if (ret[0] instanceof Date && ret[1] instanceof Date){
						isRight = isRight && assertTime((Date)ret[0],(Date)ret[1],desc + ", key:[" + actKey + "],target value:[" + tgtNodeObj + "],actual value:[" + actNodeObj+"]",isWriteRet);
					}else{
						isRight = isRight && LoggerHelper.verifyEquals(ret[0], ret[1], desc + ", key:[" + actKey + "],target value:[" + tgtNodeObj + "],actual value:[" + actNodeObj+"]",isWriteRet);
					}
					
				} catch (Exception e) {
					e.printStackTrace();
					LoggerHelper.failure(desc+", key:[" + actKey + "],target value:[" + tgtNodeObj + "],actual value:[" + actNodeObj+"]",isWriteRet);
					return false;
				}
				
			} else {
				isRight = isRight &&  LoggerHelper.verifyEquals(true, false,desc+", 期望值在实际值中不存在  key:[" + actKey + "]",isWriteRet);
			}
		}
		
		return isRight;
	}


	public static boolean assertResultEqual(Map<String, String> tgtAndActKeyPaths, JSONObject tgtObject,
			Map<String, Object> actRetMap, String desc,boolean isWriteRet) {
		return  assertResultEqual(tgtAndActKeyPaths, tgtObject, new JSONObject(actRetMap), desc,isWriteRet);
	}




	public static boolean assertResultEqual(Map<String, String> tgtAndActKeyPaths, JSONObject tgtObject,
			JSONObject actObject, String desc,boolean isWriteRet) {
		LoggerHelper.verifyNotNull( tgtAndActKeyPaths , desc + ",tgtAndActKeyPaths should not be null",isWriteRet);
		LoggerHelper.verifyNotNull( tgtObject, desc + ",tgtObject should not be null",isWriteRet);
		LoggerHelper.verifyNotNull( actObject, desc + ",actObject should not be null",isWriteRet);

		boolean isRight = true;
		
		for (String tgtKeyPath : tgtAndActKeyPaths.keySet()) {
			String actKeyPath = tgtAndActKeyPaths.get(tgtKeyPath) == null ? tgtKeyPath
					: tgtAndActKeyPaths.get(tgtKeyPath);

			if (JsonBeanHelper.isJsonBeanNodeExist(tgtObject, tgtKeyPath)) {
				if (JsonBeanHelper.isJsonBeanNodeExist(actObject, actKeyPath)) {
					Object tgtNodeObj = JsonBeanHelper.getJsonBeanNodeObj(tgtObject, tgtKeyPath);
					Object actNodeObj = JsonBeanHelper.getJsonBeanNodeObj(actObject, actKeyPath);
					try {
						Object[] ret = checkWorkAround(tgtNodeObj, actNodeObj);
						isRight = isRight && LoggerHelper.verifyEquals(ret[0], ret[1],desc + " ,期望值 key:[" + tgtKeyPath + "]和实际值 key:[" + actKeyPath + "] 比较检查",isWriteRet);

					} catch (Exception e) {
						LoggerHelper.failure(desc +", key:[" + tgtKeyPath + "],target value:[" + tgtNodeObj + "],actual value:[" + actNodeObj+"]",isWriteRet);
					}

				} else {
					isRight = isRight && LoggerHelper.verifyEquals(true, false, desc + ", 实际值集合中不存在 key:[" + actKeyPath + "]",isWriteRet);
				}
			} else {
				isRight = isRight && LoggerHelper.verifyEquals(true, false, desc + ", 期望值集合中不存在 key:[" + tgtKeyPath + "]",isWriteRet);
			}
		}
		
		return isRight;
		
	}

	public static boolean assertResultEqual(Map<String, String> tgtAndActKeyPaths, JSONObject tgtObject,
			JSONObject actObject,boolean isWriteRet) {
		return assertResultEqual(tgtAndActKeyPaths, tgtObject, actObject, "",isWriteRet);
	}

	private static Object[] checkWorkAround(Object tgtNodeObj, Object actNodeObj) {
		try{
			// for number
			if (tgtNodeObj != null && actNodeObj != null) {
				// 整数，小数，负数
				Pattern pattern = Pattern.compile("\\d+\\.\\d+$|-\\d+\\.\\d+$|^\\d+$|-\\d+$");
				boolean tgtMathcPtnAndActMatchPth = (pattern.matcher(tgtNodeObj.toString()).find()
						&& pattern.matcher(actNodeObj.toString()).find());
	
				boolean tgtIsNotNumAndActIsNum = !(StringUtils.isNumeric(tgtNodeObj.toString()))
						&& (StringUtils.isNumeric(actNodeObj.toString()));
	
				boolean tgtIsNumAndActIsNotNum = (StringUtils.isNumeric(tgtNodeObj.toString()))
						&& !(StringUtils.isNumeric(actNodeObj.toString()));
	
				if (tgtIsNotNumAndActIsNum || tgtIsNumAndActIsNotNum || tgtMathcPtnAndActMatchPth) {
					tgtNodeObj = Double.parseDouble(tgtNodeObj.toString());
					actNodeObj = Double.parseDouble(actNodeObj.toString());
				}
			} else {
				// for null and "","null" ->""
				tgtNodeObj = (tgtNodeObj == null) ? "" : tgtNodeObj;
				actNodeObj = (actNodeObj == null) ? "" : actNodeObj;
			}
			
			return new Object[] { tgtNodeObj, actNodeObj };
		}catch (Exception e){
			
		}
		return new Object[] { tgtNodeObj, actNodeObj };
		
	}



	public static boolean checkArray(String[] array1, String[] array2, String desc,boolean isWriteRet) {
		try {
			Arrays.sort(array1);
			Arrays.sort(array2);
			
			StringBuffer a1 = new StringBuffer();
			for(int i=0;i<array1.length;i++){
				a1.append(array1[i]+", ");
			}
			
			
			StringBuffer a2 = new StringBuffer();
			for(int i=0;i<array2.length;i++){
				a2.append(array2[i]+", ");
			}
			
			
			boolean aa = Arrays.equals(array1, array2);
			if (aa == true) {
				LoggerHelper.verifyEquals(true, aa, desc + ",两个数组中的值相同,["+a1+"],["+a2+"]",isWriteRet);
			} else {
				LoggerHelper.verifyEquals(true, aa, desc + ",两个数组中的值不相同,["+a1+"],["+a2+"]",isWriteRet);
			}
			
			return aa;
		} catch (Exception e) {
			LoggerHelper.failure(e.getMessage(),isWriteRet);
		}
		return false;
		
	}


	public static boolean checkArray(List strList1, List strList2,String desc,boolean isWriteRet) {
		Object[] objs1 = strList1.toArray();
		String[] strs1 = (String[]) strList1.toArray(new String[0]);

		Object[] objs2 = strList2.toArray();
		String[] strs2 = (String[]) strList2.toArray(new String[0]);

		 return checkArray(strs1, strs2,desc,isWriteRet);

	}
	

	/**
	 * 2个JSONArray转数组数组对比
	 * 
	 * @param strList1
	 * @param strList2
	 * @throws JSONException
	 * @throws Exception
	 */
	public static boolean checkArray(JSONArray strList1, JSONArray strList2, String desc,boolean isWriteRet) throws Exception {
		String[] strstring1 = new String[strList1.length()];
		String[] strstring2 = new String[strList2.length()];

		for (int i = 0; i < strList1.length(); i++) {
			strstring1[i] = strList1.getString(i);
		}

		for (int i = 0; i < strList2.length(); i++) {
			strstring2[i] = strList2.getString(i);
		}

	 return checkArray(strstring1, strstring2, desc,isWriteRet);

	}


}
